package cn.yunyichina.provider.clinic.listener;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.listener.MessageListener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.yunyichina.provider.clinic.constant.CacheConstant;
import cn.yunyichina.provider.clinic.service.impl.PayServiceImpl;
import cn.yunyichina.provider.clinic.utils.DateUtils;
import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.data.SpringContextHandler;
import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.CacheService;
import cn.yunyichina.provider.iface.entity.base.OrderExceptionVo;
import cn.yunyichina.provider.iface.entity.base.OrderExtVo;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.pay.notify.PayNotifyWechatMedicalMessage;
import cn.yunyichina.utils.convert.JsonUtils;

public class ClinicWechatMedicalMessageListener implements MessageListener<Integer, String> {
    private Logger logger = LoggerFactory.getLogger(ClinicWechatMedicalMessageListener.class);
    @Autowired
    private PayServiceImpl payService;

    public void onMessage(ConsumerRecord<Integer, String> integerStringConsumerRecord) {
        String xmlString = integerStringConsumerRecord.value();
        logger.info("微信医保支付回调，入参xmlString=" + xmlString);

        try {
            PayNotifyWechatMedicalMessage entity = JsonUtils.parseObject(xmlString,
                    PayNotifyWechatMedicalMessage.class);
            String orderNo = entity.getOrderNo();
            String openId = entity.getOpenid();
            String appId = entity.getAppid();
            BigDecimal payAmount = new BigDecimal(entity.getPayAmount());
            BigDecimal totalAmount = new BigDecimal(entity.getTotalAmount());
            BigDecimal insuranceAmount = new BigDecimal(entity.getInsuranceAmount());

            Map<String, String> map = new HashMap<String, String>();
            map.put("order_no", orderNo);
            logger.info("微信医保支付回调, 订单号" + orderNo + ", 调base模块, 查询订单信息入参request=" + JSONObject.toJSONString(map));
            Response ordResponse = BaseService.callUnderlineFromInternal("yyt.base.order.by.order.no.out.get",
                    JsonUtils.toJsonString(map));
            logger.info(
                    "微信医保支付回调, 订单号" + orderNo + ", 调base模块, 查询订单信息返回response=" + JSONObject.toJSONString(ordResponse));
            if (!"0".equals(ordResponse.getResultCode())) {
                logger.info("微信医保支付回调, 订单号" + orderNo + ", 调base模块, 查询订单信息失败，未找到对应的订单信息");
            }
            OrderExtVo order = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);
            order.setPaymentDealId(entity.getPayOrderNo());
            order.setIsInsurance((short) 1);
            order.setInsuranceMode((short) 2);
            order.setPayMode((short) 16);
            order.setIsPayHandled(1);//支付是否通知并处理0：否，1：是
            logger.info("微信医保支付回调, 订单号" + orderNo + ", 调base模块, 更新订单信息入参request=" + JSONObject.toJSONString(order));
            BaseService.callUnderlineFromInternal("yyt.base.order.update", JsonUtils.toJsonString(order));

            Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("yyt_order_no", orderNo);
            dataMap.put("pay_time", DateUtils.dateToString(new Date()));
            dataMap.put("user_id", StringUtils.isNotBlank(openId) ? openId : order.getOpenId());
            dataMap.put("payee_app_id", appId);

            dataMap.put("is_from_inner", "1");
            dataMap.put("pay_mode", "16");

            logger.info("微信医保支付回调, 订单号" + orderNo + ", 原订单payAmount=" + order.getPayAmount());
            order.setPayAmount(totalAmount.subtract(insuranceAmount).intValue());
            order.setPayRealAmount(order.getPayAmount());
            dataMap.put("pay_amount", order.getPayAmount());
            logger.info("微信医保支付回调, 订单号" + orderNo + ", 回调修改后payAmount=" + order.getPayAmount());
            logger.info("微信医保支付回调, 订单号" + orderNo + ", 原订单AccountAmount=" + order.getAccountAmount());
            // order.setAccountAmount(outsideCardFee_b.multiply(new
            // BigDecimal(100)).intValue());
            logger.info("微信医保支付回调, 订单号" + orderNo + ", 回调修改后AccountAmount=" + order.getAccountAmount());
            logger.info("微信医保支付回调, 订单号" + orderNo + ", 原订单InsuranceAmount=" + order.getInsuranceAmount());
            // modify:zkw
            order.setInsuranceRealAmount(insuranceAmount.intValue());
            logger.info("微信医保支付回调, 订单号" + orderNo + ", 回调修改后InsuranceAmount=" + order.getInsuranceAmount());

            String responseContent = (String) entity.getResponseContent();

            String tempStr = null;
            try {
                // 因为支付宝传入进来的参数中含有"{、}"、"[、]"等这些字符，所以要进行替换才能进行JSON解析
                tempStr = responseContent.replace("\"{", "{");
                tempStr = tempStr.replace("}\"", "}");
                tempStr = tempStr.replace("\"[", "[");
                tempStr = tempStr.replace("]\"", "]");
            } catch (Exception e) {
                addOrderToExceptionList(order, "微信医保支付回调, 订单号" + orderNo + ", 解析settlement或payment出现了异常！");
                logger.error("微信医保支付回调, 订单号" + orderNo + ", 解析settlement或payment出现了异常！", e);
                throw e;
            }

            Map<String, String> extraParamsMap = JsonUtils.parseObject(order.getExtraParams(), HashMap.class);
            extraParamsMap.put("industry_sepc_detail", tempStr);
            order.setExtraParams(JSON.toJSONString(extraParamsMap));
            logger.info("微信医保支付回调, 订单号" + orderNo + ", 调base模块, 更新订单信息入参request=" + JSONObject.toJSONString(order));
            BaseService.callUnderlineFromInternal("yyt.base.order.update", JsonUtils.toJsonString(order));

            if (payService == null) {
                payService = SpringContextHandler.getBean(PayServiceImpl.class);
            }
            Response response = payService.ackPayOrderByOrderNoOut(JsonUtils.toJsonString(dataMap), "");
            logger.info("微信医保支付回调, 订单号" + orderNo + ", 调写单返回response=" + JSONObject.toJSONString(response));
            if (!"0".equals(response.getResultCode())) {
                //记录写单的异常信息
                String errMsg = response.getResultMessage();

                Map<String, String> tmpMap = new HashMap<String, String>();
                tmpMap.put("order_no", orderNo);
                Response orderRes = BaseService.callUnderlineFromInternal("yyt.base.order.by.order.no.out.get",
                        JsonUtils.toJsonString(tmpMap));
                logger.info(
                        "微信医保支付回调, 订单号" + orderNo + ", 调base模块, 查询订单信息返回response=" + JSONObject.toJSONString(orderRes));
                if (!"0".equals(orderRes.getResultCode())) {
                    logger.info("微信医保支付回调, 订单号" + orderNo + ", 调base模块, 查询订单信息失败，未找到对应的订单信息");
                }
                order = JsonUtils.parseObject(orderRes.getResult(), OrderExtVo.class);
                order.setOrderStatusException();
                logger.info("微信医保支付回调, 订单号" + orderNo + ", 调base模块, 更新订单信息入参request=" + JSONObject.toJSONString(order));
                BaseService.callUnderlineFromInternal("yyt.base.order.update", JsonUtils.toJsonString(order));
                addOrderToExceptionList(order, errMsg);
            }
        } catch (Exception e) {
            logger.error("微信医保支付回调报错", e);
        }
        logger.info("微信医保支付回调结束");
    }

    private void addOrderToExceptionList(OrderExtVo vo, String errMsg) {
        logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 订单order=" + JSON.toJSONString(vo));
        boolean isAdd = true;
        try {
            logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 调用base模块, 查询是否已经存在异常单入参request=" + JSON.toJSONString(vo));
            Response response = BaseService.callUnderlineFromInternal("yyt.base.order.exception.by.order.no.get",
                    JsonUtils.toJsonString(vo));
            logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 调用base模块, 查询是否已经存在异常单返回response=" + JSON.toJSONString(response));
            if (!"0".equals(response.getResultCode())) {
                logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 调用base模块, 查询异常单信息失败");
            }

            OrderExceptionVo oe = JsonUtils.parseObject(response.getResult(), OrderExceptionVo.class);
            if (oe != null) {
                isAdd = false;
            }
        } catch (Exception e) {
            logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 查询异常单是否存在报错。");
        }

        if (isAdd) {
            OrderExceptionVo record = new OrderExceptionVo();
            record.setBranchCode(vo.getBranchCode());
            record.setBranchId(vo.getBranchId());
            record.setBranchName(vo.getBranchName());
            record.setCreatedTime(DateUtils.dateToString(new Date()));
            record.setExceptionHandlerCount(0);
            record.setRefundHandlerCount(0);
            record.setId(PKGenerator.generateId());
            record.setIsInsurance(vo.getIsInsurance());
            record.setOrderNo(vo.getOrderNo());
            record.setOrderType(vo.getOrderType());
            record.setOrgCode(vo.getOrgCode());
            record.setOrgId(vo.getOrgId());
            record.setOrgName(vo.getOrgName());
            record.setPlatformCode(vo.getPlatformCode());
            record.setPlatformId(vo.getPlatformId());
            record.setPlatformName(vo.getPlatformName());
            record.setPlatformOrgAppCode(vo.getPlatformOrgAppCode());
            record.setUpdateTime(DateUtils.dateToString(new Date()));
            record.setHandlerResult((short) 0);
            record.setHisQueryState((short) 0);
            record.setInsuranceHandlerFlag((short) 0);
            record.setSelfPayHandlerFlag((short) 0);
            //记录写单的异常信息
            record.setExceptionReason(errMsg);
            record.setExceptionClass("Clinic-ClinicWechatMedicalMessageListener");

            logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 调用base模块, 添加异常单record=" + JSON.toJSONString(record));
            CacheService.setGlobalKey(CacheConstant.CACHE_CLINIC_MODULE, CacheConstant.CACHE_CLINIC_PAY_EXCEPTION_ORDER,
                    record.getOrderNo(), JSON.toJSONString(record), CacheConstant.CACHE_NOT_EXPIRETIME);

            BaseService.callUnderlineFromInternal("", "yyt.base.order.exception.add", JsonUtils.toJsonString(record));
        }
        logger.info("添加异常单信息, 订单号" + vo.getOrderNo() + ", 结束");
    }

}
